package xin.clips.web.controller.gy.analy;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import xin.clips.common.annotation.VisistLog;
import xin.clips.common.core.controller.BaseController;
import xin.clips.common.core.domain.AjaxResult;
import xin.clips.common.core.domain.entity.SysDictData;
import xin.clips.common.core.domain.entity.SysUser;
import xin.clips.common.core.page.TableDataInfo;
import xin.clips.common.enums.gy.WorkOrderStatusEnum;
import xin.clips.common.utils.DictUtils;
import xin.clips.common.utils.ShiroUtils;
import xin.clips.common.utils.StringUtils;
import xin.clips.system.domain.SysLogininfor;
import xin.clips.system.domain.SysVisitLog;
import xin.clips.system.domain.gy.GyDevice;
import xin.clips.system.domain.gy.GyDeviceAlarmRecord;
import xin.clips.system.domain.gy.GyWorkOrder;
import xin.clips.system.dto.GyDeviceStatusDataDTO;
import xin.clips.system.dto.MachineInfoDTO;
import xin.clips.system.dto.NameValueDataDTO;
import xin.clips.system.service.ISysDictDataService;
import xin.clips.system.service.ISysLogininforService;
import xin.clips.system.service.ISysUserService;
import xin.clips.system.service.ISysVisitLogService;
import xin.clips.system.service.gy.IGyDeviceAlarmRecordService;
import xin.clips.system.service.gy.IGyDeviceEarlywarnRecordService;
import xin.clips.system.service.gy.IGyDeviceService;
import xin.clips.system.service.gy.IGyWorkOrderService;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 设备分析
 *
 * @author clips
 * @date 2023-03-15
 */
@Controller
@RequestMapping("/gy/deviceTypeAnaly")
public class DeviceTypeAnalyController extends BaseController {

    private String prefix = "gy/deviceTypeAnaly";

    @Autowired
    private IGyDeviceAlarmRecordService gyDeviceAlarmRecordService;

    @Autowired
    private IGyDeviceService deviceService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private ISysLogininforService logininforService;

    @Autowired
    private ISysVisitLogService visitLogService;

    @Autowired
    private IGyDeviceEarlywarnRecordService gyDeviceEarlywarnRecordService;


    @Autowired
    private IGyWorkOrderService gyWorkOrderService;

    @RequiresPermissions("gy:deviceTypeAnaly:count")
    @VisistLog(title = "设备分析")
    @GetMapping()
    public String deviceStatusAnaly(ModelMap mmap) {
        Long userId = ShiroUtils.getUserId(); // 获取用户id
        SysUser sysUser = userService.selectUserById(userId);
        String locationId = sysUser.getLocationId();
        SysDictData typeDictData = new SysDictData();
        typeDictData.setDictType("gy_device_type");      //设备类型
        List<SysDictData> typeDicts = dictDataService.selectDictDataList(typeDictData);
        SysDictData statusDictData = new SysDictData();
        statusDictData.setDictType("gy_device_status");  //设备状态
        List<SysDictData> statusDicts = dictDataService.selectDictDataList(statusDictData);
        List<String> typeList = new ArrayList<>();
        for (SysDictData typeData : typeDicts) {
            typeList.add(typeData.getDictLabel());
        }
        List<String> statusList = new ArrayList<>();
        List<GyDeviceStatusDataDTO> gyDeviceStatusDatumDTOS = new ArrayList<>();
        for (SysDictData statusData : statusDicts) {
            statusList.add(statusData.getDictLabel());
            GyDeviceStatusDataDTO gyDeviceStatusDataDTO = new GyDeviceStatusDataDTO();
            gyDeviceStatusDataDTO.setName(statusData.getDictLabel());
            gyDeviceStatusDatumDTOS.add(gyDeviceStatusDataDTO);
        }
        List<ArrayList> list = new ArrayList();

        for (SysDictData statusData : statusDicts) {
            ArrayList temp = new ArrayList();
            for (SysDictData type : typeDicts) {
                GyDevice device = new GyDevice();
                if (StringUtils.isNotEmpty(locationId)) {
                    device.setLocationId(Integer.parseInt(locationId));//根据用户所在的学院统计
                }
                device.setDeviceType(Integer.parseInt(type.getDictValue()));
                device.setDeviceStatus(Integer.parseInt(statusData.getDictValue()));
                Integer total = deviceService.selectGyDeviceByDeviceTypeAndStatus(device);//根据设备类型，状态
                temp.add(total.toString());
            }
            list.add(temp);
        }

        mmap.put("typeArray", typeList.toArray());  //类型组装['打磨机器人', '机械臂', '巡检机器人', '冲压机床', '数控机床']
        mmap.put("gyDeviceStatusAnalys", gyDeviceStatusDatumDTOS);
        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < list.size(); i++) {
            //构建json数组
            JSONObject stObject = new JSONObject();
            stObject.put("name", statusList.get(i));
            stObject.put("type", "bar");
            stObject.put("stack", "one");
            //  stObject.put("emphasis", "itemStyle: {\n" +
            //   "                shadowBlur: 10,\n" +
            //   "                shadowColor: 'rgba(0,0,0,0.3)'\n" +
            //    "            }");
            stObject.put("data", list.get(i).stream().toArray());
            jsonArray.add(stObject);
        }
        mmap.put("jsonArray", jsonArray);

        /*统计最新一周登录量、访问量*/

        SysVisitLog visistLog = new SysVisitLog();
        List<SysVisitLog> sceneData = visitLogService.selectVisitTop3(visistLog);
        List<String> keyData = new ArrayList();
        List<String> valueData = new ArrayList();
        for (SysVisitLog temp : sceneData) {
            keyData.add(temp.getModuleName());
            valueData.add(temp.getCount());
        }

        mmap.put("keyData", keyData.toArray());
        mmap.put("valueData", valueData.toArray());

        //工单趋势分析
        Map<String, String> waitDataMap = new HashMap<>(); //工单趋势分析  待处理
        Map<String, String> processingDayMap = new HashMap<>(); //工单趋势分析  处理中
        Map<String, String> finshDayMap = new HashMap<>(); //工单趋势分析  申请完成
        Map<String, String> auditedDayMap = new HashMap<>(); //工单趋势分析  已审核

        List<String> dateList = new ArrayList<>();
        String startTime = "";
        String endTime = "";
        for (int i = 7; i >= 0; i--) {
            String date = LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            if (i == 7) {
                startTime = date;
            }
            if (i == 0) {
                endTime = date;
            }
            dateList.add(date);
            waitDataMap.put(date, "0");
            processingDayMap.put(date, "0");
            finshDayMap.put(date, "0");
            auditedDayMap.put(date, "0");
        }
        GyWorkOrder gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.WAIT.getCode()));
        List<GyWorkOrder> workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            waitDataMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> waitCountArray = new ArrayList<>();
        for (String date : dateList) {
            waitCountArray.add(waitDataMap.get(date)); //将值转换为string集合。
        }

        //处理中
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.PROCESSING.getCode()));

        workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            processingDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> processingCountArray = new ArrayList<>();
        for (String date : dateList) {
            processingCountArray.add(processingDayMap.get(date)); //将值转换为string集合。
        }


        //处理完成
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.AUDITFINISH.getCode()));

        workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            finshDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> finshCountArray = new ArrayList<>();
        for (String date : dateList) {
            finshCountArray.add(finshDayMap.get(date)); //将值转换为string集合。
        }

        //已审核
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        workOrders = gyWorkOrderService.selectWorkOrderAuthedAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            auditedDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> auditedCountArray = new ArrayList<>();
        for (String date : dateList) {
            auditedCountArray.add(auditedDayMap.get(date)); //将值转换为string集合。
        }

        mmap.put("waitCountArray", waitCountArray.toArray());  //待处理
        mmap.put("processingCountArray", processingCountArray.toArray()); //处理中
        mmap.put("finshCountArray", finshCountArray.toArray()); //处理中
        mmap.put("auditedCountArray", auditedCountArray.toArray()); //处理中
        mmap.put("rqArray", dateList.toArray());//日期array

        /**/

        int alarmTotal = gyDeviceAlarmRecordService.selectTotal();
        int earlyWarnTotal = gyDeviceEarlywarnRecordService.selectTotal();
        List<String> alarmData = new ArrayList();
        List<String> alarmAndWaringValueData = new ArrayList();

        alarmData.add("告警");
        alarmData.add("预警");
        alarmAndWaringValueData.add(String.valueOf(alarmTotal));
        alarmAndWaringValueData.add(String.valueOf(earlyWarnTotal));

        mmap.put("alarmData", alarmData.toArray());
        mmap.put("alarmAndWaringValueData", alarmAndWaringValueData.toArray());

        /*返回登录、用户访问量的 柱状图统计*/
        Long loginTotal = logininforService.selectTotal();
        Long loginAndVistorTotal = visitLogService.selectTotal();
        List<String> loginData = new ArrayList();
        List<String> loginAndVistorTotalValueData = new ArrayList();

        loginData.add("登录数");
        loginData.add("用户访问数");
        loginAndVistorTotalValueData.add(String.valueOf(loginTotal));
        loginAndVistorTotalValueData.add(String.valueOf(loginAndVistorTotal));

        mmap.put("loginTotal", loginData.toArray());
        mmap.put("loginAndVistorTotalValueData", loginAndVistorTotalValueData.toArray());


        /*设备总类统计*/

        List<NameValueDataDTO> deviceTypeDTOS = new ArrayList<>();
        for (SysDictData typeData : typeDicts) {
            NameValueDataDTO gyDeviceTypeDTO = new NameValueDataDTO(typeData.getDictLabel(), "0");
            deviceTypeDTOS.add(gyDeviceTypeDTO);
        }
        GyDevice gyDevice = new GyDevice();

        List<GyDevice> deviceTypelist = deviceService.selectGyDeviceByDeviceType(gyDevice);

        for (NameValueDataDTO count : deviceTypeDTOS) {
            for (GyDevice device : deviceTypelist) {
                if (device.getDeviceType().toString()
                        .equals(DictUtils.getDictValue("gy_device_type", count.getName()))) {
                    count.setValue(device.getCount().toString());
                }
            }
        }

        mmap.put("deviceTypelist", deviceTypeDTOS.toArray());

        /*设备运行时间，设备产量*/

        List<String> machineRuntimeNames = new ArrayList<>();
        List<String> machineRuntimeValues = new ArrayList<>();

        List<String> machineProductionNames = new ArrayList<>();
        List<String> machineProductionValues =new ArrayList<>();

        NameValueDataDTO machineProductionInfo = new NameValueDataDTO();
        List<MachineInfoDTO> machineInfoDTOS = deviceService.selectDeviceMachineAnalyInfo(new GyDevice());
        for (MachineInfoDTO temp : machineInfoDTOS) {
            machineRuntimeNames.add(temp.getDeviceName());
            machineRuntimeValues.add(temp.getRunTime());

            machineProductionNames.add(temp.getDeviceName());
            machineProductionValues.add(temp.getProduction());
        }


        mmap.put("machineRuntimeNames", machineRuntimeNames.toArray());
        mmap.put("machineRuntimeValues", machineRuntimeValues.toArray());
        mmap.put("machineProductionNames", machineProductionNames.toArray());
        mmap.put("machineProductionValues", machineProductionValues.toArray());
        /**/

        return prefix + "/deviceTypeAnaly";
    }

    /**
     * 设备状态分析
     */
    @RequiresPermissions("gy:deviceTypeAnaly:count")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(GyDeviceAlarmRecord gyDeviceAlarmRecord) {

        startPage();
        List<GyDeviceAlarmRecord> list = gyDeviceAlarmRecordService.selectGyDeviceAlarmRecordList(gyDeviceAlarmRecord);
        return getDataTable(list);
    }

    /**
     * 导出设备消息绑定列表
     */
    @RequestMapping("search")
    @ResponseBody
    public AjaxResult search(String startTime, String endTime) {

        List<String> dateList = new ArrayList<>();
        Map<String, String> waitDataMap = new HashMap<>(); //工单趋势分析  待处理
        Map<String, String> processingDayMap = new HashMap<>(); //工单趋势分析  处理中
        Map<String, String> finshDayMap = new HashMap<>(); //工单趋势分析  申请完成
        Map<String, String> auditedDayMap = new HashMap<>(); //工单趋势分析  已审核
        dateList.add(startTime);
        waitDataMap.put(startTime, "0");
        processingDayMap.put(startTime, "0");
        finshDayMap.put(startTime, "0");
        auditedDayMap.put(startTime, "0");
        String date = startTime;
        do {
            date = LocalDate.parse(date).plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            dateList.add(date);
            waitDataMap.put(date, "0");
            processingDayMap.put(date, "0");
            finshDayMap.put(date, "0");
            auditedDayMap.put(date, "0");
        } while (!endTime.equals(date));


        SysLogininfor logininfor = new SysLogininfor();
        logininfor.getParams().put("beginTime", startTime + " 00:00:00");
        logininfor.getParams().put("endTime", endTime + " 23:59:59");


        GyWorkOrder gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.WAIT.getCode()));
        List<GyWorkOrder> workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            waitDataMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> waitCountArray = new ArrayList<>();
        for (String temp: dateList) {
            waitCountArray.add(waitDataMap.get(temp)); //将值转换为string集合。
        }

        //处理中
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.PROCESSING.getCode()));

        workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            processingDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> processingCountArray = new ArrayList<>();
        for (String temp : dateList) {
            processingCountArray.add(processingDayMap.get(temp)); //将值转换为string集合。
        }


        //处理完成
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        gyWorkOrder.setWorkStatus(Integer.parseInt(WorkOrderStatusEnum.AUDITFINISH.getCode()));

        workOrders = gyWorkOrderService.selectWorkOrderAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            finshDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> finshCountArray = new ArrayList<>();
        for (String temp : dateList) {
            finshCountArray.add(finshDayMap.get(temp)); //将值转换为string集合。
        }

        //已审核
        gyWorkOrder = new GyWorkOrder();
        gyWorkOrder.getParams().put("beginTime", startTime + " 00:00:00");
        gyWorkOrder.getParams().put("endTime", endTime + " 23:59:59");
        workOrders = gyWorkOrderService.selectWorkOrderAuthedAnalyByTime(gyWorkOrder);

        for (GyWorkOrder workOrder : workOrders) {
            auditedDayMap.put(workOrder.getDat(), workOrder.getCount().toString()); //将取到的数据覆盖初始的
        }

        ArrayList<String> auditedCountArray = new ArrayList<>();
        for (String temp : dateList) {
            auditedCountArray.add(auditedDayMap.get(temp)); //将值转换为string集合。
        }
        AjaxResult ajaxResult = new AjaxResult();


        ajaxResult.put("waitCountArray", waitCountArray.toArray());  //
        ajaxResult.put("processingCountArray", processingCountArray.toArray());  //
        ajaxResult.put("finshCountArray", finshCountArray.toArray());  //
        ajaxResult.put("auditedCountArray", auditedCountArray.toArray());  //
        ajaxResult.put("rqArray", dateList.toArray());//日期


        return ajaxResult;
    }


}



